package basic

import (
	"errors"
	"gitee.com/Luna-CY/hui-hui/server/http/response"
	"github.com/gin-gonic/gin"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/mem"
	"github.com/shirou/gopsutil/v3/net"
)

type DashboardResponse struct {
	Cpus   []float64 `json:"cpus" validate:"required"` // CPU核心列表
	Memory struct {
		Virtual struct {
			Total uint64 `json:"total" validate:"required"` // 总量
			Used  uint64 `json:"used" validate:"required"`  // 已使用
			Free  uint64 `json:"free" validate:"required"`  // 空闲
		} `json:"virtual" validate:"required"` // 虚拟内存
		Swap struct {
			Total uint64 `json:"total" validate:"required"` // 总量
			Used  uint64 `json:"used" validate:"required"`  // 已使用
			Free  uint64 `json:"free" validate:"required"`  // 空闲
		} `json:"swap" validate:"required"` // 交换内存
	} `json:"memory"`
	Disk struct {
		Usage struct {
			Total uint64 `json:"total" validate:"required"` // 总量
			Used  uint64 `json:"used" validate:"required"`  // 已使用
			Free  uint64 `json:"free" validate:"required"`  // 空闲
		} `json:"usage" validate:"required"` // 使用量
		IOCounter struct {
			Read  uint64 `json:"read" validate:"required"`  // 读
			Write uint64 `json:"write" validate:"required"` // 写
		} `json:"io_counter" validate:"required"` // IO统计
	} `json:"disk" validate:"required"` // 磁盘
	Networks []Network `json:"network" validate:"required"` // 网络
}

type Network struct {
	Name string `json:"name" validate:"required"` // 网络名称
	Up   struct {
		Total   uint64 `json:"total" validate:"required"`   // 总量
		Current uint64 `json:"current" validate:"required"` // 当前
	} `json:"up" validate:"required"` // 上行
	Down struct {
		Total   uint64 `json:"total" validate:"required"`   // 总量
		Current uint64 `json:"current" validate:"required"` // 当前
	} `json:"down" validate:"required"` // 下行
}

func (cls *Basic) Dashboard(_ *gin.Context) (int, any, error) {
	var res = DashboardResponse{}

	// 统计CPU使用率
	res.Cpus, _ = cpu.Percent(0, true)

	// 统计虚拟内存使用率
	memory, err := mem.VirtualMemory()
	if nil != err {
		return response.Unknown, nil, errors.New(err.Error())
	}

	res.Memory.Virtual.Total = memory.Total
	res.Memory.Virtual.Used = memory.Used
	res.Memory.Virtual.Free = memory.Free

	// 统计交换内存使用率
	swap, err := mem.SwapMemory()
	if nil != err {
		return response.Unknown, nil, errors.New(err.Error())
	}

	res.Memory.Swap.Total = swap.Total
	res.Memory.Swap.Used = swap.Used
	res.Memory.Swap.Free = swap.Free

	// 统计磁盘使用率
	usage, err := disk.Usage("/")
	if nil != err {
		return response.Unknown, nil, errors.New(err.Error())
	}

	res.Disk.Usage.Total = usage.Total
	res.Disk.Usage.Used = usage.Used
	res.Disk.Usage.Free = usage.Free
	res.Disk.IOCounter.Read, res.Disk.IOCounter.Write = cls.counter.DiskGetIOCount()

	networks, err := net.IOCounters(true)
	if nil != err {
		return response.Unknown, nil, errors.New(err.Error())
	}

	for _, network := range networks {
		var cu, cd, tu, td = cls.counter.NetworkGetIOCount(network.Name)

		var item = Network{Name: network.Name}
		item.Up.Current = cu
		item.Up.Total = tu
		item.Down.Current = cd
		item.Down.Total = td

		res.Networks = append(res.Networks, item)
	}

	return response.Ok, res, nil
}
